﻿using System;
using System.Web;
using System.Web.Security;

using iOak.Business.Users;
using iOak.Domain.Users;

namespace iOak.Business.Authentication
{
    public partial class FormsAuthenticationService
    {
        private readonly HttpContextBase _httpContext;
        private readonly UserService _userService;
        private readonly TimeSpan _expirationTimeSpan;
        private User _cachedUser;

        public FormsAuthenticationService()
        {
            _httpContext = new HttpContextWrapper(HttpContext.Current) as HttpContextBase;
            _userService = new UserService();
            _expirationTimeSpan = FormsAuthentication.Timeout;
        }

        public virtual void SignIn(User user, bool isPersistentCookie)
        {
            var now = DateTime.UtcNow.ToLocalTime();

            var ticket = new FormsAuthenticationTicket(
                1 /*version*/,
               user.UserName,
                now,
                now.Add(_expirationTimeSpan),
                isPersistentCookie,
                user.UserName,
                FormsAuthentication.FormsCookiePath);

            var encryptedTicket = FormsAuthentication.Encrypt(ticket);

            var cookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket);
            cookie.HttpOnly = true;
            cookie.Expires = now.Add(_expirationTimeSpan);
            cookie.Secure = FormsAuthentication.RequireSSL;
            cookie.Path = FormsAuthentication.FormsCookiePath;
            if (FormsAuthentication.CookieDomain != null)
            {
                cookie.Domain = FormsAuthentication.CookieDomain;
            }

            _httpContext.Response.Cookies.Add(cookie);
            _cachedUser = user;
        }

        public virtual void SignOut()
        {
            _cachedUser = null;
            FormsAuthentication.SignOut();
        }

        public virtual User GetAuthenticatedUser()
        {
            //if (_cachedUser != null)
            //    return _cachedUser;

            if (_httpContext == null ||
               _httpContext.Request == null ||
               !_httpContext.Request.IsAuthenticated ||
               !(_httpContext.User.Identity is FormsIdentity))
            {
                return null;
            }

            var formsIdentity = (FormsIdentity)_httpContext.User.Identity;
            var user = GetAuthenticatedUserFromTicket(formsIdentity.Ticket);
            if (user != null && user.Active)
                _cachedUser = user;
            return _cachedUser;
        }

        public virtual User GetAuthenticatedUserFromTicket(FormsAuthenticationTicket ticket)
        {
            if (ticket == null)
                throw new ArgumentNullException("ticket");

            var username = ticket.UserData;

            if (String.IsNullOrWhiteSpace(username))
                return null;

            var user = _userService.GetUserByName(username);

            return user;
        }


    }
}
